/*
//  Copyright © 2014 Allen County Public Library.

  //        ACPL Mobile is free software: This program is distributed and you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.  ACPL Mobile is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, including without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with ACPL Mobile. If not, see http://www.gnu.org/licenses/.
 * Author: James Harpe
 * 
 * Description: This class handles web service calls associated with account information.
 * 
 */

package us.in.lib.acpl.Mobile_ACPL.ws;

import java.io.IOException;
import java.io.StringReader;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.util.Xml;
import android.view.Gravity;
import android.view.View;
import android.widget.Toast;

import us.in.lib.acpl.Mobile_ACPL.AccountActivity;
import us.in.lib.acpl.Mobile_ACPL.R;
import us.in.lib.acpl.Mobile_ACPL.context.Mobile_ACPL;
import us.in.lib.acpl.Mobile_ACPL.patron.Checkout;
import us.in.lib.acpl.Mobile_ACPL.patron.Fine;
import us.in.lib.acpl.Mobile_ACPL.patron.Hold;
import us.in.lib.acpl.Mobile_ACPL.util.RestClient;
import us.in.lib.acpl.Mobile_ACPL.util.RestClient.RequestMethod;

public class AccountInfoHandler {
	public static final String ACCOUNT_URL = Mobile_ACPL.WS_HOST+"/symws/rest/patron/lookupMyAccountInfo";

	private List<Checkout> checkouts;
	private List<Hold> holds;
	private List<Fine> fines;
	private String totalCheckouts;
	private String totalHolds;
	private String totalFines;
	private boolean error;
	private SharedPreferences prefs;

	private AccountActivity act;

	public AccountInfoHandler(AccountActivity act) {
		this.act = act;
		this.prefs = act.getSharedPreferences("myPrefs",
				Context.MODE_WORLD_WRITEABLE);
		this.checkouts = new ArrayList<Checkout>();
		this.holds = new ArrayList<Hold>();
		this.fines = new ArrayList<Fine>();
		this.error=false;
	}

	public void lookupAccountInfo() {

		LoginHandler handler = new LoginHandler();
		handler.getNewSessionToken(prefs, act);

		if (prefs.getString("sessionToken", null) != null) {
			new GetAccountInfoTask().execute();
		}else{
			act.findViewById(R.id.accountBar).setVisibility(View.GONE);
		}

	}

	public List<Checkout> getCheckouts() {
		return checkouts;
	}

	public List<Hold> getHolds() {
		return holds;
	}

	public List<Fine> getFines() {
		return fines;
	}

	public String getTotalCheckouts() {
		return totalCheckouts;
	}

	public String getTotalHolds() {
		return totalHolds;
	}

	public String getTotalFines() {
		double allFines=0;
		for(int i=0; i<fines.size();i++){
			allFines+=Double.parseDouble(fines.get(i).getAmountOutstanding());
		}
		DecimalFormat formatter = new DecimalFormat("#.00"); 
		return formatter.format(allFines);
	}

	private class GetAccountInfoTask extends AsyncTask<Void, Void, Void> {

		@Override
		protected Void doInBackground(Void... arg0) {

			String sessionToken = prefs.getString("sessionToken", null);
			RestClient client = new RestClient(ACCOUNT_URL);
			client.AddHeader("x-sirs-clientID", SearchCatalogHandler.CLIENT_ID);
			client.AddParam("sessionToken", sessionToken);
			client.AddParam("includePatronCirculationInfo", "true");
			client.AddParam("includePatronCheckoutInfo", "ALLEXCEPTLOST");
			client.AddParam("includePatronHoldInfo", "ACTIVE");
			client.AddParam("includeFeeInfo", "UNPAID_FEES");

			try {
				client.Execute(RequestMethod.POST);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			String response = client.getResponse();
			if(response==null){
				error=true;
				return null;
			}else{
				error=false;
			}
			
			Hold currHold = new Hold();
			Checkout currCheckout = new Checkout();
			Fine currFine = new Fine();
			int currScope = 0;

			checkouts.clear();
			holds.clear();
			fines.clear();

			XmlPullParser parser = Xml.newPullParser();
			try {
				parser.setInput(new StringReader(response));

				int eventType = parser.next();
				while (eventType != XmlPullParser.END_DOCUMENT) {
					if (eventType == XmlPullParser.END_TAG) {
						String name = parser.getName();
						if (name.equalsIgnoreCase("patronCirculationInfo")) {

						}
						if (name.equalsIgnoreCase("patronCheckoutInfo")) {
							checkouts.add(currCheckout);
							currCheckout = new Checkout();
						}
						if (name.equalsIgnoreCase("patronHoldInfo")) {
							holds.add(currHold);
							currHold = new Hold();
						}
						if (name.equalsIgnoreCase("feeInfo")) {
							fines.add(currFine);
							currFine = new Fine();
						}
					}
					if (eventType == XmlPullParser.START_TAG) {
						String name = parser.getName();
						// Determine which type of object upcoming values belong
						// to.
						if (name.equalsIgnoreCase("numberOfCheckouts")) {
							totalCheckouts = parser.nextText();
						}
						if (name.equalsIgnoreCase("numberOfHolds")) {
							totalHolds = parser.nextText();
						}
						if (name.equalsIgnoreCase("estimatedFines")) {
							totalFines = parser.nextText();
						}
						if (name.equalsIgnoreCase("patronCheckoutInfo")) {
							currScope = 0;
						}
						if (name.equalsIgnoreCase("patronHoldInfo")) {
							currScope = 1;
						}
						if (name.equalsIgnoreCase("feeInfo")) {
							currScope = 2;
						}
						if (name.equalsIgnoreCase("title")) {
							if (currScope == 0) {
								currCheckout.setTitle(parser.nextText());
							}
							if (currScope == 1) {
								currHold.setTitle(parser.nextText());
							}
							if (currScope == 2) {
								currFine.setTitle(parser.nextText());
							}
						}
						if (name.equalsIgnoreCase("author")) {
							if (currScope == 0) {
								currCheckout.setAuthor(parser.nextText());
							}
							if (currScope == 1) {
								currHold.setAuthor(parser.nextText());
							}
							if (currScope == 2) {
								currFine.setAuthor(parser.nextText());
							}
						}
						if (name.equalsIgnoreCase("itemID")) {
							if (currScope == 0) {
								currCheckout.setItemId(parser.nextText());
							}
							if (currScope == 1) {
								currHold.setItemId(parser.nextText());
							}
							if (currScope == 2) {
								currFine.setItemId(parser.nextText());
							}
						}
						if (name.equalsIgnoreCase("callNumber")) {
							if (currScope == 0) {
								currCheckout.setCallNumber(parser.nextText());
							}
							if (currScope == 1) {
								currHold.setCallNumber(parser.nextText());
							}
							if (currScope == 2) {
								currFine.setCallNumber(parser.nextText());
							}
						}
						if (name.equalsIgnoreCase("dueDate")) {
							currCheckout.setDueDate(parser.nextText());
						}
						if (name.equalsIgnoreCase("checkoutDate")) {
							currCheckout.setCheckoutDate(parser.nextText());
						}
						if (name.equalsIgnoreCase("renewals")) {
							currCheckout.setTimesRenewed(parser.nextText());
						}
						if (name.equalsIgnoreCase("overdue")) {
							currCheckout.setOverdue(Boolean.parseBoolean(parser
									.nextText()));
						}
						if (name.equalsIgnoreCase("holdKey")) {
							currHold.setHoldKey(parser.nextText());
						}
						if (name.equalsIgnoreCase("pickupLibraryID")) {
							currHold.setPickupLibrary(parser.nextText());
						}
						if (name.equalsIgnoreCase("placedDate")) {
							currHold.setPlacedDate(parser.nextText());
						}
						if (name.equalsIgnoreCase("available")) {
							currHold.setAvailable(Boolean.parseBoolean(parser
									.nextText()));
						}
						if (name.equalsIgnoreCase("queuePosition")) {
							currHold.setQueuePosition(parser.nextText());
						}
						if (name.equalsIgnoreCase("queueLength")) {
							currHold.setQueueLength(parser.nextText());
						}
						if (name.equalsIgnoreCase("billReasonID")) {
							currFine.setBillReason(parser.nextText());
						}
						if (name.equalsIgnoreCase("amountOutstanding")) {
							currFine.setAmountOutstanding(parser.nextText());
						}
						if (name.equalsIgnoreCase("dateBilled")) {
							currFine.setDateBilled(parser.nextText());
						}

					}
					eventType = parser.next();
				}

			} catch (XmlPullParserException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}

			return null;
		}

		@Override
		protected void onPostExecute(Void obj) {
			if(error){
				Toast toast = Toast.makeText(act, "An error occurred. Please try your operation again.", Toast.LENGTH_LONG);
				toast.setGravity(Gravity.CENTER, 0, 0);
				toast.show();
			}else{
				Collections.sort(checkouts);
			
				act.handleAccountResponse();
			}
			
		}
	}

}
